package com.bayss.core.service.coupon;

import com.bayss.core.constant.ResultMsg;
import com.bayss.core.entity.coupon.Coupon;
import com.bayss.core.entity.coupon.CouponExample;
import com.bayss.core.entity.coupon.CouponUid;
import com.bayss.core.entity.coupon.CouponUidExample;
import com.bayss.core.entity.coupon.mapper.CouponMapper;
import com.bayss.core.entity.coupon.mapper.CouponUidMapper;
import com.bayss.core.enums.CouponStatus;
import com.bayss.core.enums.CouponType;
import com.bayss.core.model.UserCoupon;
import com.bayss.core.util.BigDecimalUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by LDL on 2019/12/11.
 */
@Service
public class CouponService {
    public static final Logger logger = LoggerFactory.getLogger(CouponService.class);
    @Autowired
    private CouponUidMapper couponUidMapper;
    @Autowired
    private CouponMapper couponMapper;

    /**
     * 分页查询
     */
    public PageInfo<Coupon> getByPage(Integer page, Integer pageSize) {
        CouponExample example = new CouponExample();
        example.setOrderByClause("create_time desc");
        PageHelper.startPage(page, pageSize);
        PageInfo<Coupon> result = PageHelper.startPage(page, pageSize).doSelectPageInfo(() -> couponMapper.selectByExample(example));
        return result;
    }

    /**
     * 按类型查询
     *
     * @param discountType
     */
    public List<Coupon> list(Integer discountType) {
        CouponExample example = new CouponExample();
        CouponExample.Criteria criteria = example.createCriteria();
        if (discountType != null) {
            criteria.andDiscountTypeEqualTo(discountType);
        }
        criteria.andEndTimeGreaterThan(new Date());
        return couponMapper.selectByExample(example);
    }

    /**
     * 根据用户id查询优惠券
     *
     * @param userId
     * @return
     */
    public List<Coupon> findByUserId(Long userId, Integer orderPrice) {
        CouponUidExample example = new CouponUidExample();
        example.createCriteria().andUidEqualTo(userId)
                .andStatusEqualTo(Byte.valueOf(CouponStatus.normal.getVal() + ""));
        List<CouponUid> list = couponUidMapper.selectByExample(example);
        if (list == null || list.size() == 0) {
            return new ArrayList<>();
        }

        List<Integer> idList = list.stream().map(CouponUid::getCouponId).collect(Collectors.toList());
        CouponExample couponExample = new CouponExample();
        couponExample.createCriteria().andIdIn(idList);
        List<Coupon> couponList = couponMapper.selectByExample(couponExample);

        if (orderPrice != null && orderPrice.intValue() > 0) {
            //根据订单金额设置优惠券可用状态
            for (Coupon coupon : couponList) {
                if (coupon.getDiscountType().equals(CouponType.subtract.getVal())) {
                    //满减
                    if (orderPrice < coupon.getDiscountContion()) {
                        coupon.setStatus(CouponStatus.invalid.getVal());
                        coupon.setDisplay("订单金额不满" + coupon.getDiscountContion() / 100 + "元");
                    }
                }
            }
        }
        return couponList;
    }

    /**
     * 优惠多少金额
     */
    public Integer afterCouponPrice(Integer totalPrice, Long uid, Long couponId) {
        CouponUidExample example = new CouponUidExample();
        example.createCriteria().andUidEqualTo(uid)
                .andCouponIdEqualTo(couponId);
        List<CouponUid> list = couponUidMapper.selectByExample(example);
        if (list == null || list.size() == 0) {
            logger.error("优惠券不存在,uid:{},couponId:{}", uid, couponId);
            return 0;
        }
        CouponUid couponUidDB = list.get(0);
        if (couponUidDB.getStatus().intValue() != CouponStatus.normal.getVal()) {
            logger.error("优惠券状态不可用,uid:{},couponId:{}", uid, couponId);
            return 0;
        }

        Coupon coupon = couponMapper.selectByPrimaryKey(couponId.intValue());
        if (coupon.getDiscountType().equals(CouponType.subtract.getVal())) {
            //满减
            if (totalPrice < coupon.getDiscountContion()) {
                //订单金额不满足优惠券使用条件
                return 0;
            }
            return coupon.getDiscountValue();
        }
        if (coupon.getDiscountType().equals(CouponType.rebate.getVal())) {
            // 打折
            try {
                Double discountValue = (100 - coupon.getDiscountValue()) / 100d;
                Double value = BigDecimalUtil.mul(totalPrice, discountValue);
                int result = (int) BigDecimalUtil.round(value, 0);
                return result;
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return 0;
    }

    /**
     * 校验优惠券是否可用
     */
    public ResultMsg checkCouponEnable(Long uid, Integer orderPrice, Long couponId) {
        CouponUidExample example = new CouponUidExample();
        example.createCriteria().andUidEqualTo(uid)
                .andCouponIdEqualTo(couponId)
                .andStatusEqualTo(Byte.valueOf(CouponStatus.normal.getVal() + ""));
        List<CouponUid> list = couponUidMapper.selectByExample(example);
        if (list == null || list.size() == 0) {
            logger.error("当前优惠券已失效,id:{}", couponId);
            return ResultMsg.fail(250, "当前优惠券已失效");
        }

        Coupon coupon = couponMapper.selectByPrimaryKey(couponId.intValue());
        if (coupon.getDiscountType().equals(CouponType.subtract.getVal())) {
            //满减
            if (orderPrice < coupon.getDiscountContion()) {
                return ResultMsg.fail(250, "订单金额不满" + coupon.getDiscountContion() + "元");
            }
        }
        return ResultMsg.success();
    }

    /**
     * 删除
     *
     * @param id
     */
    public void deleteById(Integer id) {
        couponMapper.deleteByPrimaryKey(id);
    }

    /**
     * 用户优惠券锁定状态
     *
     * @param couponId
     * @param uid
     */
    public boolean lockCouponUid(Long couponId, Long uid) {
        try {
            int n = couponUidMapper.updateStatusByCouponId(couponId.intValue(), uid.intValue(), CouponStatus.locked.getVal());
            return n > 0 ? true : false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 用户优惠券已使用状态
     *
     * @param couponId
     * @param uid
     */
    public boolean useCouponUid(Long couponId, Long uid) {
        try {
            int n = couponUidMapper.updateStatusByCouponId(couponId.intValue(), uid.intValue(), CouponStatus.invalid.getVal());
            return n > 0 ? true : false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 修改优惠券
     *
     * @param coupon
     */
    public void updateCoupon(Coupon coupon) {
        if (String.valueOf(CouponType.subtract.getVal()).equals(coupon.getDiscountType() + "")) {
            coupon.setDesces("满" + coupon.getDiscountContion() + "元减" + coupon.getDiscountValue() + "元");
        }
        if (String.valueOf(CouponType.rebate.getVal()).equals(coupon.getDiscountType() + "")) {
            coupon.setDesces(coupon.getDiscountValue() + "折");
        }
        couponMapper.updateByPrimaryKeySelective(coupon);
    }

    /**
     * 新建优惠券
     *
     * @param coupon
     * @return
     */
    public ResultMsg addCoupon(Coupon coupon) {
        if (coupon.getDiscountType() == null) {
            return ResultMsg.fail(-1, "优惠券类型不能为空");
        }
        if (coupon.getDiscountValue() == null) {
            return ResultMsg.fail(-1, "优惠券优惠金额不能为空");
        }
        if (coupon.getDiscountType().equals(CouponType.subtract.getVal()) && coupon.getDiscountContion() == null) {
            return ResultMsg.fail(-1, "优惠券满减条件不能为空");
        }

        if (coupon.getDiscountType().equals(CouponType.subtract.getVal())) {
            coupon.setDesces("满" + coupon.getDiscountContion() / 100 + "元减" + coupon.getDiscountValue() / 100 + "元");
        }
        if (coupon.getDiscountType().equals(CouponType.rebate.getVal())) {
            coupon.setDesces(coupon.getDiscountValue() + "折");
        }
        coupon.setCreateTime(new Date());
        couponMapper.insertSelective(coupon);
        return ResultMsg.success();
    }

    /**
     * 发放优惠券
     */
    public void addCouponUser(String couponIds, String userIds) {
        String[] couponArr = couponIds.split(",");
        String[] userIdArr = userIds.split(",");
        List<CouponUid> list = new ArrayList<>();
        for (String couponId : couponArr) {
            for (String userId : userIdArr) {
                CouponUid c = new CouponUid();
                c.setCouponId(Integer.parseInt(couponId));
                c.setUid(Long.parseLong(userId));
                c.setStatus(Byte.valueOf(CouponStatus.normal.getVal() + ""));
                c.setCreateTime(new Date());
                list.add(c);
            }
        }
        couponUidMapper.batchInsert(list);
    }

    public List<UserCoupon> findUserCoupon(Integer uid) {
        CouponUidExample example = new CouponUidExample();
        example.createCriteria().andUidEqualTo(uid.longValue());
        List<CouponUid> list = couponUidMapper.selectByExample(example);
        List<UserCoupon> userCoupons = new ArrayList<>();

        for (CouponUid cUid : list) {
            Coupon c = couponMapper.selectByPrimaryKey(cUid.getCouponId());
            if (c == null) {
                continue;
            }
            UserCoupon userCoupon = new UserCoupon();
            BeanUtils.copyProperties(c, userCoupon);
            userCoupon.setStatus(cUid.getStatus().intValue());
            userCoupon.setUid(uid.longValue());
            userCoupons.add(userCoupon);
        }
        return userCoupons;
    }
}
